/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vng.zing.zprofile.thrift.wrapper;

import com.vng.zing.calc.thrift.Profile;
import com.vng.zing.calc.thrift.ProfilePage;
import com.vng.zing.calc.thrift.ROLE;
import com.vng.zing.calc.thrift.SOURCE;
import com.vng.zing.calc.thrift.STATUS;
import com.vng.zing.calc.thrift.ZProfileService;
import com.vng.zing.common.ZCommonDef;
import com.vng.zing.configer.ZConfig;
import com.vng.zing.logger.ZLogger;
import com.vng.zing.thriftpool.TClientPool;
import com.vng.zing.thriftpool.ZClientPoolUtil;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;

/**
 *
 * @author namnq
 */
public class ZProfileClient {

    private static final Class _ThisClass = ZProfileClient.class;
    private static final Logger _Logger = ZLogger.getLogger(_ThisClass);
    private final String _name;
    private TClientPool.BizzConfig _bizzCfg;
    private ZProfileService.Client _aclient; //unused

    private ZConfig config = ZConfig.Instance;

    public ZProfileClient(String name) {
        assert (name != null && !name.isEmpty());
        _name = name;
        _initialize();

    }

    private void _initialize() {
        ZClientPoolUtil.SetDefaultPoolProp(_ThisClass //clazzOfCfg
                , _name //instName
                , config.getString("thrift.host", "localhost:9000") //host
                , null //auth
                , ZCommonDef.TClientTimeoutMilisecsDefault //timeout
                , ZCommonDef.TClientNRetriesDefault //nretry
                , ZCommonDef.TClientMaxRdAtimeDefault //maxRdAtime
                , ZCommonDef.TClientMaxWrAtimeDefault //maxWrAtime
        );
        ZClientPoolUtil.GetListPools(_ThisClass, _name, new ZProfileService.Client.Factory()); //auto create pools
        _bizzCfg = ZClientPoolUtil.GetBizzCfg(_ThisClass, _name);
    }

    private TClientPool<ZProfileService.Client> getClientPool() {
        return (TClientPool<ZProfileService.Client>) ZClientPoolUtil.GetPool(_ThisClass, _name);
    }

    private TClientPool.BizzConfig getBizzCfg() {
        return _bizzCfg;
    }

    ///~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// util functions
    ///
    private static void Log(Priority level, Throwable t) {
        _Logger.log(level, null, t);
    }

    private static void Log(Priority level, Throwable t, int retry) {
        if (retry > 0) {
            String message = "Request's still failed at retry " + retry;
            _Logger.log(level, message, t);
        } else {
            _Logger.log(level, null, t);
        }
    }

    public static List<List<Integer/*KType*/>> SplitListKeys(List<Integer/*KType*/> listKeys, int mkeysAtime) {
                if (listKeys == null) {
                    return null;
                }
                //correct mkeysAtime
                if (mkeysAtime < 1) {
                    mkeysAtime = 1;
                }
                List<List<Integer/*KType*/>> ret = new LinkedList<List<Integer/*KType*/>>();
                int size = listKeys.size();
                if (size <= mkeysAtime) {
                    ret.add(listKeys);
                    return ret;
                }
                int nsubList = size / mkeysAtime;
                for (int i = 0; i < nsubList; ++i) {
                    int startIndex = i * mkeysAtime;
                    ret.add(listKeys.subList(startIndex, startIndex + mkeysAtime));
                }
                int lastListSz = size % mkeysAtime;
                if (lastListSz > 0) {
                    ret.add(listKeys.subList(size - lastListSz, size));
                }
                return ret;
            }

            public Profile getProfile(int id) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile profile = cli.getProfile(id);
                    return profile;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public Map<Short, String> getAllCity() {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Map<Short, String> citiesMap = cli.getAllCity();
                    _Logger.info("Get all cities with " + citiesMap.size());
                    return citiesMap;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public Profile createProfile(Profile profile) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile result = cli.createProfile(profile);
                    _Logger.info("insert profile  :" + profile.toString());
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public boolean validUsername(String username) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return false;
                }
                try {
                    boolean result = cli.validUsername(username);
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return false;
            }

            public Profile logIn(String username, String password) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile result = cli.logIn(username, password);
                    _Logger.info("Log in  :" + username);
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public Profile changePassword(int profileId, String currentPassword, String newPassword) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile result = cli.changePassword(profileId, currentPassword, newPassword);
                    _Logger.info("changePassword  :" + profileId);
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public Profile updateProfile(Profile profile) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile result = cli.updateProfile(profile);
                    _Logger.info("update  :" + profile.toString());
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public ProfilePage getAllProfile(int limit, int offset) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    ProfilePage ret = cli.getAllProfile(limit, offset);
                    _Logger.info("get all profile with " + ret.getProfileMap().size());
                    return ret;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

            public boolean changeStatus(int profileId, STATUS status) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return false;
                }
                try {
                    boolean ret = cli.changeStatus(profileId, status);
                    _Logger.info("change status " + profileId + status);
                    getClientPool().returnClient(cli);
                    return ret;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return false;
            }

         public Profile getSocialProfile(SOURCE source, String UID) {
                ZProfileService.Client cli = getClientPool().borrowClient();
                if (cli == null) {
                    return null;
                }
                try {
                    Profile result = cli.getSocialProfile(source, UID);
                    _Logger.info("get social profile  :" + result.toString());
                    return result;
                } catch (Exception ex) {
                    _Logger.error(ex);
                } finally {
                    getClientPool().returnClient(cli);
                }
                return null;
            }

}
